/** sps_conf.cpp - configure file implemention
 *
 * This file contains the configure file implemention. If you add some configure
 * directive in configure file, you may add some codes in this file.
 *
 */

#include "sps_config.h"

SpsConf*     SpsConf::conf_         = NULL;
bool         SpsConf::destroyed_    = false;

SpsConf& SpsConf::instance()
{
  if (!conf_) {
    if (destroyed_) {
      onDeadReference();
    } else {
      onCreate();
    }
  }

  return *conf_;
}


int SpsConf::loadConf(const char *file)
{
  FILE   *fp  = NULL;
  char   *buf = NULL;
  size_t  len;
  int     ret = -1;

  fp = fopen(file, "r", O_READ);
  if (fp == NULL) {
    SpsLog::instance().logAlert("open(\"%s\") failed");
    goto ERR_EXIT;
  }

  fseek(fp, 0L, SEEK_END);
  len = ftell(fp);
  rewind(fp);

  buf = new char[len + 1];
  
  size_t r = fread(buf, 1, len, fp);
  if (r != len) {
    SpsLog::instance().logAlert("fread(\"%s\") failed");
    goto ERR_EXIT;
  }

  ret = loadConfString(buf, len);

 ERR_EXIT:

  if (buf) {
    delete [] buf;
  }
  
  if (fp) {
    fclose(fp);
  }
  return 0;
}

const char* SpsConf::get_host()
{
  return host_.c_str();
}

const char* SpsConf::get_serv()
{
  return serv_.c_str();
}

unsigned int SpsConf::get_timeout_wait_num()
{
  return timeout_wait_num_;
}

unsigned long SpsConf::get_reconnect_time_sec()
{
  return reconnect_time_sec_;
}

unsigned long SpsConf::get_reconnect_time_usec()
{
  return reconnect_time_usec_;
}

unsigned long SpsConf::get_connect_timeout_sec()
{
  return connect_timeout_sec_;
}

unsigned long SpsConf::get_connect_timeout_usec()
{
  return connect_timeout_usec_;
}

/*******************************************************************************
 * Private functions                                                           *
 ******************************************************************************/

SpsConf::SpsConf()
  : host_("10.10.10.219")
  , serv_("8090")
  , timeout_wait_num_(5)
  , reconnect_time_sec_(5)
  , reconnect_time_usec_(0)
  , connect_timeout_sec_(15)
  , connect_timeout_usec_(0)
{

}

SpsConf::~SpsConf()
{
  destroyed_ = true;
}

SpsConf::SpsConf(const SpsConf& rhs)
{

}

SpsConf& SpsConf::operator=(const SpsConf& rhs)
{
  return *conf_;
}

void SpsConf::onCreate()
{
  static SpsConf conf;

  conf_ = &conf;
}

void SpsConf::onDeadReference()
{
  /* TODO: Recreate if conf_ is destroyed. */
}

int SpsConf::loadConfString(const char *buf, size_t len)
{
  char *p = (char *)buf;
  char *k = NULL;
  char *v = NULL;
  char *e = p + len;

  /* TODO: Parse the configure string. */
  while (p < e) {

    /* skip the space */
    while (*p++ == ' ') /* void */;
    
    /* This is a comment, skip it */
    if (*p == '#') {
      while (*p++ == '\n') {
	p++;
	continue;
      }
    }

    k = p;
    while (*p++ != ' ') /* void */;
    *p++ = 0;
    /* skip the */
    while (*p++ == ' ') /* void */;
    
  }
  
  return 0;
}
